#!/bin/bash

# SVN自动化部署脚本
# 用法: ./svn_setup.sh -p 项目名 -w 网站目录 -u 用户名 -s 密码 [-i SVN根目录]

# 默认配置
SVN_ROOT="/var/svn"
SVN_USERS=()
SVN_PASSWORDS=()

# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # 无颜色

# 函数: 显示帮助信息
show_help() {
    echo -e "${YELLOW}SVN自动化部署脚本${NC}"
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -p, --project    项目名称 (必需)"
    echo "  -w, --webdir     网站目录 (必需)"
    echo "  -u, --users      SVN用户名列表 (格式: 用户名1:密码1,用户名2:密码2)"
    echo "  -i, --svnroot    SVN根目录 (默认: /var/svn)"
    echo "  -h, --help       显示此帮助信息"
    echo ""
    echo "示例:"
    echo "  $0 -p myproject -w /data/website -u admin:123456,dev:dev123"
    exit 1
}

# 函数: 记录日志
log() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}

# 函数: 错误日志
error_log() {
    echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] 错误:${NC} $1" >&2
}

# 函数: 检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        error_log "$1 命令未找到，请先安装"
        exit 1
    fi
}

# 函数: 安装SVN
install_svn() {
    log "检查SVN是否已安装..."
    if ! command -v svnserve &> /dev/null; then
        log "正在安装SVN..."
        
        # 检测包管理器
        if command -v yum &> /dev/null; then
            yum install -y subversion
        elif command -v dnf &> /dev/null; then
            dnf install -y subversion
        elif command -v apt-get &> /dev/null; then
            apt-get update
            apt-get install -y subversion
        elif command -v apk &> /dev/null; then
            apk update
            apk add subversion
        else
            error_log "无法识别包管理器，请手动安装SVN"
            exit 1
        fi
        
        # 检查包管理器安装结果
        if ! command -v svnserve &> /dev/null; then
            log "包管理器安装失败，尝试源码编译..."
            cd /tmp
            wget https://archive.apache.org/dist/subversion/subversion-1.14.2.tar.gz
            tar -xzf subversion-1.14.2.tar.gz
            cd subversion-1.14.2
            ./configure --prefix=/usr/local
            make && make install
            
            if ! command -v svnserve &> /dev/null; then
                error_log "SVN安装失败，请手动安装SVN服务"
                exit 1
            fi
        fi
        
        log "SVN安装成功"
    else
        log "SVN已安装，版本信息:"
        svnserve --version | head -n 1
    fi
}

# 函数: 创建SVN仓库
create_repository() {
    local project_name=$1
    local svn_path="$SVN_ROOT/$project_name"
    
    log "创建项目仓库: $project_name"
    
    # 检查仓库是否已存在
    if [ -d "$svn_path" ]; then
        error_log "仓库 $project_name 已存在于 $SVN_ROOT"
        exit 1
    fi
    
    # 创建SVN根目录(如果不存在)
    mkdir -p $SVN_ROOT
    
    # 创建仓库
    svnadmin create "$svn_path" || {
        error_log "创建仓库失败"
        exit 1
    }
    
    log "仓库创建成功: $svn_path"
}

# 函数: 配置SVN仓库
configure_repository() {
    local project_name=$1
    local svn_path="$SVN_ROOT/$project_name"
    local conf_path="$svn_path/conf"
    
    log "配置项目仓库: $project_name"

    # 配置svnserve.conf
    if grep -q "\[general\]" "$conf_path/svnserve.conf"; then
        sed -i '/\[general\]/a\
anon-access = none\
auth-access = write\
password-db = passwd\
authz-db = authz\
realm = /var/svn/'"$project_name"'
' "$conf_path/svnserve.conf"
    else
        cat >> "$conf_path/svnserve.conf" <<EOF

[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = /var/svn/$project_name
EOF
    fi

    # 配置passwd文件
    log "配置 passwd 文件..."
    if [ ! -f "$conf_path/passwd" ] || ! grep -q "\[users\]" "$conf_path/passwd"; then
        echo "[users]" > "$conf_path/passwd"
    fi
    
    for ((i=0; i<${#SVN_USERS[@]}; i++)); do
        echo "${SVN_USERS[$i]} = ${SVN_PASSWORDS[$i]}" >> "$conf_path/passwd"
        log "添加用户: ${SVN_USERS[$i]}"
    done

    # 修复authz配置 - 确保[/]节存在
    log "配置 authz 文件..."
    if [ ! -f "$conf_path/authz" ]; then
        # 文件不存在时创建完整结构
        echo "[/]" >> "$conf_path/authz"
    elif ! grep -q "^\[/\]" "$conf_path/authz"; then
        # 文件存在但缺少[/]节时追加
        echo "[/]" >> "$conf_path/authz"
    fi
    
    # 添加用户权限（跳过已存在的配置）
	for user in "${SVN_USERS[@]}"; do
        if ! grep -q "^$user = rw" "$conf_path/authz"; then
            echo "$user = rw" >> "$conf_path/authz"
        fi
    done

    log "仓库配置完成"
}


# 函数: 配置自动同步钩子
configure_hook() {
    local project_name=$1
    local web_dir=$2
    local svn_path="$SVN_ROOT/$project_name"
    local hook_path="$svn_path/hooks/post-commit"
    
    log "配置自动同步钩子: $project_name -> $web_dir"
    
    # 创建网站目录(如果不存在)
    mkdir -p "$web_dir"
    
    # 创建post-commit钩子
    cat > "$hook_path" << EOF
#!/bin/sh
export LANG=en_US.utf8
SVN_PATH=/usr/bin/svn
WEB_PATH=$web_dir
\$SVN_PATH update \$WEB_PATH --username '${SVN_USERS[0]}' --password '${SVN_PASSWORDS[0]}' --no-auth-cache
EOF
    
    # 设置权限
    chmod 755 "$hook_path"
    
    # 如果系统有www用户，则设置www用户权限
    if id "www" &>/dev/null; then
        chown www:www "$hook_path"
        log "已设置www用户权限"
    else
        log "警告: 系统中未找到www用户，跳过权限设置"
    fi
    
    log "自动同步钩子配置完成"
}

# 函数: 初始检出
initial_checkout() {
    local project_name=$1
    local web_dir=$2
    
    log "执行初始检出: $project_name -> $web_dir"
    
    # 检出仓库到网站目录
    svn co "svn://localhost/$project_name" "$web_dir" --username "${SVN_USERS[0]}" --password "${SVN_PASSWORDS[0]}" || {
        error_log "初始检出失败"
        return 1
    }
    
    log "初始检出完成"
}

# 函数: 启动SVN服务
start_svn_service() {
    log "启动SVN服务..."
    
    # 先尝试杀死现有的svnserve进程
    if pgrep svnserve > /dev/null; then
        killall svnserve
        log "已停止现有SVN服务"
    fi
    
    # 启动服务
    svnserve -d -r "$SVN_ROOT" || {
        error_log "SVN服务启动失败"
        exit 1
    }
    
    log "SVN服务启动成功"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
        -p|--project)
            PROJECT_NAME="$2"
            shift 2
            ;;
        -w|--webdir)
            WEB_DIR="$2"
            shift 2
            ;;
        -u|--users)
            IFS=',' read -ra USER_PAIRS <<< "$2"
            for pair in "${USER_PAIRS[@]}"; do
                IFS=':' read -r user pass <<< "$pair"
                SVN_USERS+=("$user")
                SVN_PASSWORDS+=("$pass")
            done
            shift 2
            ;;
        -i|--svnroot)
            SVN_ROOT="$2"
            shift 2
            ;;
        -h|--help)
            show_help
            ;;
        *)
            error_log "未知参数: $1"
            show_help
            ;;
    esac
done

# 检查必需参数
if [ -z "$PROJECT_NAME" ] || [ -z "$WEB_DIR" ] || [ ${#SVN_USERS[@]} -eq 0 ]; then
    error_log "缺少必需参数"
    show_help
fi

# 主流程
log "开始SVN自动化部署流程..."
log "项目名称: $PROJECT_NAME"
log "网站目录: $WEB_DIR"
log "SVN根目录: $SVN_ROOT"
log "用户数量: ${#SVN_USERS[@]}"

# 检查SVN命令
check_command svnadmin
check_command svnserve

# 安装SVN(如果需要)
install_svn

# 创建仓库
create_repository "$PROJECT_NAME"

# 配置仓库
configure_repository "$PROJECT_NAME"

# 启动SVN服务
start_svn_service

# 配置自动同步钩子
configure_hook "$PROJECT_NAME" "$WEB_DIR"

# 初始检出
initial_checkout "$PROJECT_NAME" "$WEB_DIR"

log "SVN自动化部署完成!"
log "SVN地址: svn://localhost/$PROJECT_NAME"
log "网站目录: $WEB_DIR"
log "用户名: ${SVN_USERS[0]}"
log "密码: ${SVN_PASSWORDS[0]}"
log ""
log "使用以下命令重启SVN服务:"
log "  killall svnserve && svnserve -d -r $SVN_ROOT"
log ""
log "使用以下命令清除SVN信息(如需要):"
log "  find $WEB_DIR -type d -name \".svn\"|xargs rm -rf"
